import React, { Component } from 'react';
import { View, Chart, Tooltip, Geom, Coord } from 'bizcharts';
import { DataView } from '@antv/data-set';
import Ellipsis from '@/components/Ellipsis';
import ResizeObserver from 'resize-observer-polyfill';
import { themeLight, themeDark, commonConfig, pieConfig, fitHeight } from '../config';
import styles from '../index.less';

const { defaultTheme } = commonConfig;
const {
  defaultInnerRadius,
  defaultTitleFontSize,
  defaultTitleLines,
  defaultTitleMarginTop,
} = pieConfig;

/* eslint react/no-danger:0 */
class DoublePie extends Component {
  state = {
    height: 0,
    viewportScale: window.viewportScale,
  };

  componentDidMount() {
    this.resizeObserver();
    window.addEventListener('resize', this.resize, { passive: true });
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resize);
  }

  getG2Instance = chart => {
    this.chart = chart;
  };

  handleRoot = n => {
    this.root = n;
  };

  resize = () => {
    this.setState({ viewportScale: window.viewportScale });
  };

  resizeObserver() {
    const ro = new ResizeObserver(entries => {
      const { width, height } = entries[0].contentRect;
      this.setState(preState => {
        if (preState.width !== width || preState.height !== height) {
          return {
            height,
          };
        }
        return null;
      });
    });
    if (this.root) {
      ro.observe(this.root);
    }
  }

  render() {
    const { height: stateHeight, viewportScale } = this.state;
    const { theme = defaultTheme } = this.props;
    const { defaultTitleColor, defaultColor } = theme === 'dark' ? themeDark : themeLight;
    const {
      style,
      height: propsHeight,
      forceFit = true,
      percent, // 外层和内层的百分比数组
      padding = 10 * viewportScale,
      inner = defaultInnerRadius,
      geomStyle = {},
      showTooltipValue = false, // true：tooltip展示具体数值，false：tooltip展示百分比
      colorOut = defaultColor, // 外层颜色
      colorIn = defaultColor, // 内层颜色
      unit,
      title,
      titleColor = defaultTitleColor,
      titleFontSize = defaultTitleFontSize,
      titleLines = defaultTitleLines, // 限制标题行数，若无需限制传0
    } = this.props;

    let { dataMax } = this.props; // 最大值
    const {
      dataOut: propsDataOut,
      dataIn: propsDataIn,
      showTooltip: propsShowTooltip = true,
    } = this.props;

    let dataOut = propsDataOut || []; // 外层数据
    let dataIn = propsDataIn || []; // 内层数据
    let showTooltip = propsShowTooltip;

    const scale = {
      x: {
        type: 'cat',
        range: [0, 1],
      },
      y: {
        min: 0,
      },
    };

    if (percent && percent.length === 2) {
      showTooltip = false;

      dataOut = [
        {
          x: '占比',
          y: parseFloat(percent[0]),
        },
        {
          x: '反比',
          y: 100 - parseFloat(percent[0]),
        },
      ];
      dataIn = [
        {
          x: '占比',
          y: parseFloat(percent[1]),
        },
        {
          x: '反比',
          y: 100 - parseFloat(percent[1]),
        },
      ];
    }

    if (dataOut && dataOut.length === 1 && dataIn && dataIn.length === 1) {
      showTooltip = false;
      const valueOut = parseFloat(dataOut[0].y) || 0;
      const valueIn = parseFloat(dataIn[0].y) || 0;
      if (!dataMax) dataMax = ((valueOut > valueIn ? valueOut : valueIn) / 2) * 3;
      const dataOutPercent = dataMax === 0 ? 0 : (valueOut / dataMax) * 100;
      dataOut = [
        {
          x: '占比',
          y: parseFloat(dataOutPercent),
        },
        {
          x: '反比',
          y: 100 - parseFloat(dataOutPercent),
        },
      ];

      const dataInPercent = dataMax === 0 ? 0 : (valueIn / dataMax) * 100;
      dataIn = [
        {
          x: '占比',
          y: parseFloat(dataInPercent),
        },
        {
          x: '反比',
          y: 100 - parseFloat(dataInPercent),
        },
      ];
    }

    const tooltip = showTooltipValue
      ? [
          'x*y',
          (x, y) => ({
            name: x,
            value: y + (unit || ''),
          }),
        ]
      : [
          'x*percent',
          (x, p) => ({
            name: x,
            value: `${(p * 100).toFixed(2)}%`,
          }),
        ];

    const dvOut = new DataView();
    dvOut.source(dataOut).transform({
      type: 'percent',
      field: 'y',
      dimension: 'x',
      as: 'percent',
    });
    const dvIn = new DataView();
    dvIn.source(dataIn).transform({
      type: 'percent',
      field: 'y',
      dimension: 'x',
      as: 'percent',
    });

    const height = propsHeight || stateHeight;

    return (
      <div ref={this.handleRoot} className={styles.pie} style={style} key={this.root}>
        <Chart
          scale={scale}
          height={height * viewportScale}
          forceFit={forceFit}
          data={dvOut}
          padding={padding}
          onGetG2Instance={this.getG2Instance}
        >
          {!!showTooltip && <Tooltip showTitle={false} />}
          <Coord type="theta" radius={1} innerRadius={inner} />
          <Geom
            type="intervalStack"
            position="percent"
            color={['x', colorOut]}
            style={geomStyle}
            tooltip={showTooltip && tooltip}
            select={false}
          />
          <View data={dvIn} scale={scale}>
            <Coord type="theta" radius={0.64} innerRadius={0.66} />
            <Geom
              type="intervalStack"
              position="percent"
              color={['x', colorIn]}
              tooltip={showTooltip && tooltip}
              select={false}
            />
          </View>
        </Chart>
        {title && (
          <div
            style={{
              color: titleColor,
              fontSize: titleFontSize * viewportScale,
              marginTop: defaultTitleMarginTop,
              height: titleLines * fitHeight(21),
              lineHeight: `${fitHeight(21)}px`,
            }}
            className={styles.title}
          >
            <Ellipsis lines={titleLines} tooltip>
              {title}
            </Ellipsis>
          </div>
        )}
      </div>
    );
  }
}

export default DoublePie;
